package net.bcxuexi.pool;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;

import net.bcxuexi.tools.MyLog;

/*
 * 调度器，保存需要调度的任务,例如计算任务超时时间
 */
public abstract class Dispatcher extends Thread {
	// 调度器的任务队列
	private BlockingQueue<Runnable> blockingQueue;
	// 调度器的工作线程池
	protected static WorkThreadPool threadPool;
	// 停止分发
	protected boolean stopDispatchThread = false;

	public Dispatcher(int corePoolSize, int maximumPoolSize) {
		threadPool = new WorkThreadPool(5, 10);
		blockingQueue = new ArrayBlockingQueue<Runnable>(500);
	}

	@Override
	public void run() {
		stopDispatchThread = false;
		while (true) {
			if (stopDispatchThread && blockingQueue.size() == 0) {
				// 结束线程池
				threadPool.stop();
				break;
			}
			dispatch();
			try {
				sleep(80);
			} catch (InterruptedException e) {
				MyLog.info("dispatcher 被中断");
				MyLog.info(e.getMessage());
				e.printStackTrace();
			}
		}
	}

	/*
	 * 调度的具体实现方法 根据stopDispatchThread决定是否停止分发
	 */
	public abstract void dispatch();

	/**
	 * 添加任务。可能发生阻断。 如果队列已满则调用此方法的线程被阻断直到BlockingQueue里面有空间再继续
	 * 
	 * @param task
	 * @throws InterruptedException
	 *             中断异常
	 */
	public void addTask(Runnable task) throws InterruptedException {
		blockingQueue.put(task);
	}

	/**
	 * 取走BlockingQueue里排在首位的对象。
	 * 若BlockingQueue为空,阻断调用此方法的线程，直到BlockingQueue有新的数据被加入
	 * 
	 * @return
	 * @throws InterruptedException
	 *             中断异常
	 */
	protected Runnable take() throws InterruptedException {
		return blockingQueue.take();
	}

	public void removeTask(Runnable task) {
		blockingQueue.remove(task);
	}

	public void startDispatch() {
		start();
	}

	/**
	 * 立即停止调度。会清空所有的任务，在执行的任务不会被停止
	 */
	public void stopDispatchNow() {
		blockingQueue.clear();
		stopDispatchThread = true;
		// 产生一次中断
		interrupt();
	}

	/**
	 * 当任务队列为空停止调度。
	 */
	public void stopDispatch() {
		stopDispatchThread = true;
		// 产生一次中断
		interrupt();
	}
}
